<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <title>多级表格联动</title></title>
    <script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.js"></script>
    <link rel="stylesheet"
          href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.css">
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
    <script src="./tmpl.js"></script>
    <style>
        .city-title ul {
            border-bottom: 2px solid #5270aa;
            padding: 0;
            overflow: hidden;
        }

        .city-title li.active {
            border-bottom-color: transparent;
            background: #5270aa;
            color: #fff;
        }

        .city-title li {
            float: left;
            width: 33.33%;
            height: 40px;
            line-height: 40px;
            text-align: center;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            cursor: pointer;
            padding: 0 5px;
        }

        .city-area {
            max-width: 600px;
        }

        .city-area>.tab-pane {
            display: none;
        }

        .city-area>.tab-pane.active {
            display: block;

        }

        .attr-list-body {
            padding: 5px 20px;
        }

        .attr-list-body label {
            margin: 0 10px;
            padding: 5px;
        }
        .attr-list-body label.active {
            color:white;
            background-color: #4c72d5;
            border-radius: 3px;
        }

        .attr-bar {
            text-align: right;
            padding: 0 10px 10px 0;
        }

        .btn {
            border-radius: 5px;
            line-height: 24px;
            padding: 5px;
            margin-right: 15px
        }

        .btn.blue-btn {
            background-color: #4c72d5;
            border: 1px solid #4c72d5;
            color: #fff;
        }

        .btn.gray-btn {
            background-color: #ddd;
            border: 1px solid #ddd;
            color: #000;
        }

        .btn.btn-small {
            width: 50px;
        }
    </style>
</head>
<dl class="filter-bar">
    <dd class="filter-tag"
        id="domicile">
        <script id="childNodeListTemplate"
                type="x-tmpl">
        {% for(var i = 0; i< o.length; i++){ %}
            <label nodeid="{%= o[i].SERVICE %}" title="{%= o[i].SERVICE_NAME %}">{%= o[i].SERVICE_NAME %}</label>
        {% } %}
    </script>
    </dd>
</dl>

<body>



    <script>
        $(function () {
            var epidemicTreedata =
                [
                    {
                        SERVICE_NAME: "佛山本地疫情数据",
                        SOURCE_NAME: "",
                        level: 1,
                        ChildNodes: [
                            { "SERVICE_NAME": "本地病例信息（确诊+疑似）", "SOURCE_TYPE": "FSKX", "PARAM_NUM": 1, "SOURCE_NAME": "佛山本地疫情数据", "EXTEND": "{\"FILED\":\"identityNo\",\"URL\":\"http://173.0.12.111:80/api/getRyPatientFsInfo\",\"IS_SINGLE\":\"1\"}", "SERVICE": "getRyPatientFsInfo", "ID": 7, level: 2 },
                            { "SERVICE_NAME": "本地密切接触者", "SOURCE_TYPE": "FSKX", "PARAM_NUM": 1, "SOURCE_NAME": "佛山本地疫情数据", "EXTEND": "{\"FILED\":\"clueIdentityNo\",\"IS_SINGLE\":\"1\",\"URL\":\"http://173.0.12.111:80/api/getRyPatientCloseContactsInfo\"}", "SERVICE": "getRyPatientCloseContactsInfo", "ID": 8, level: 2 }
                        ]
                    },
                    {
                        SERVICE_NAME: "省厅疫情数据",
                        SOURCE_NAME: "",
                        level: 1,
                        ChildNodes: [{ "SERVICE_NAME": "广东省政数局疫情隐患上报", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"zjhm\",\"URL\":\"http://{URL}/gdszsjyqyhsb\"}", "SERVICE": "gdszsjyqyhsb", "ID": 2, level: 2 }, { "SERVICE_NAME": "广东省人社医保参保人基本信息查询服务", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"gmsfhm\",\"IS_SINGLE\":\"1\"}", "SERVICE": "gdsrsybcbrjbxx", "ID": 5, level: 2 }, { "SERVICE_NAME": "广东省政数局疫情隐患上报", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"URL\":\"http://173.0.12.111:80/gdszsjyqyhsb\",\"IS_SINGLE\":\"1\"}", "SERVICE": "gdszsjyqyhsb", "ID": 6, level: 2 }, { "SERVICE_NAME": "广东省人社医保参保人基本信息", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"gmsfhm\",\"URL\":\"http://173.0.12.111:80/gdsrsybcbrjbxx\",\"IS_SINGLE\":\"0\",\"RESPONSE_PARAM\":\"kssj,zzrq,xm,gmsfhm,mzdm_dmbcms,lxdh,lx_dzmc,lxr_lxdh,dwbh,dwmc,sss_xzqh,sss_xzqhdm,tcq_xzqhdm_dmbcms,rycb_dqzt_dmbcms,ry_dqzt_dmbcms,sccb_rq\"}", "SERVICE": "gdsrsybcbrjbxx", "ID": 9, level: 2 }, { "SERVICE_NAME": "来粤体温检测员表", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"SFZH\",\"URL\":\"http://173.0.12.111:80/LYTWJCYB\",\"IS_SINGLE\":\"1\"}", "SERVICE": "LYTWJCYB", "ID": 10, level: 2 }, { "SERVICE_NAME": "来粤行程表", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"CPH\",\"URL\":\"http://173.0.12.111:80/LYXCB\",\"IS_SINGLE\":\"1\",\"IGNORE_FILED\":\"XCBID,XCM\"}", "SERVICE": "LYXCB", "ID": 11, level: 2 }, { "SERVICE_NAME": "来粤乘客表", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"SFZHM\",\"URL\":\"http://173.0.12.111:80/LYCKB\",\"IS_SINGLE\":\"1\"}", "SERVICE": "LYCKB", "ID": 12, level: 2 }, { "SERVICE_NAME": "疫情密切接触者信息", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"sfzh\",\"URL\":\"http://173.0.12.111:80/getGdyqInfo\",\"IS_SINGLE\":\"1\"}", "SERVICE": "getGdyqInfo", "ID": 13, level: 2 }, { "SERVICE_NAME": "湖北离境又入境广东的人员", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"sfzh\",\"URL\":\"http://173.0.12.111:80/gd_ryxx\",\"IS_SINGLE\":\"1\"}", "SERVICE": "gd_ryxx", "ID": 14, level: 2 }, { "SERVICE_NAME": "国家卫健委密切接触者信息", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"identityNo\",\"URL\":\"http://173.0.12.111:80/LYTWJCYB\",\"IS_SINGLE\":\"1\"}", "SERVICE": "LYTWJCYB", "ID": 15, level: 2 }, { "SERVICE_NAME": "广东名单1108_海鲜市场", "SOURCE_TYPE": "ST", "PARAM_NUM": 1, "SOURCE_NAME": "省厅疫情数据", "EXTEND": "{\"FILED\":\"SFZH\",\"URL\":\"http://173.0.12.111:80/whhxschdry\",\"IS_SINGLE\":\"1\"}", "SERVICE": "whhxschdry", "ID": 16, level: 2 }]
                    },
                    {
                        SERVICE_NAME: "佛山市疫情数据",
                        SOURCE_NAME: "",
                        level: 1,
                        ChildNodes: [{ "SERVICE_NAME": "本地密切接触者", "SOURCE_TYPE": "FSKX", "PARAM_NUM": 1, "SOURCE_NAME": "佛山市疫情数据", "EXTEND": "{\"FILED\":\"clueIdentityNo\",\"IS_SINGLE\":\"1\"}", "SERVICE": "bdmqjcz", "ID": 3, level: 2 }, { "SERVICE_NAME": "本地病例信息（确诊+疑似）", "SOURCE_TYPE": "FSKX", "PARAM_NUM": 1, "SOURCE_NAME": "佛山市疫情数据", "EXTEND": "{\"FILED\":\"identityNo\",\"IS_SINGLE\":\"1\"}", "SERVICE": "bddlxx", "ID": 4, level: 2 }]
                    },
                ]
            //初始化地址树
            initEpidemicBulkSearchTree({
                'elem': ['domicile'],
                'addressId': ['registerAreaList'],
                'tmpl': 'childNodeListTemplate',
                'selectArr': ['PERMANENT_ADDRESS'],
                'addressArr': epidemicTreedata
            });
        });
        /**
     * 初始化级联结构
     * @param {array} elem 地址HTML容器
     * @param {array} addressId 初始化省级内容的id
     * @param {string} tmpl 初始化模板
     * @param {array} selectArr 获取值的input的name
     * @param {array} addressArr 疫情数据
     */
        function initEpidemicBulkSearchTree(options) {
            var $addressWrap = options.elem;//顶级父容器
            var addressId = options.addressId;//label的父级
            var addressTmpl = options.tmpl;
            var selectArr = options.selectArr;//hideinput的name
            var addressArr = options.addressArr;
            var curAreaVal = '';//请选择的内容
            if (!selectArr) {
                selectArr = $addressWrap
            }
            $.each($addressWrap, function (i, n) {
                var areaHtml = '<div class="tree-wrap dropdown">' +
                    '<div class="dropdown-toggle" data-toggle="dropdown">' +
                    '<span class="selectedArea">请选择 </span>' +
                    '<input type="hidden" name="' + selectArr[i] + '" value="">' +
                    '<span class="glyphicon glyphicon-chevron-down" style="vertical-align:middle;margin-left: 5px;"></span>' +
                    '</div>' +
                    '<div class="dropdown-menu">' +
                    '<div class="city-title">' +
                    '<ul>' +
                    '<li ref=".city" class="active" defaultName="数据源">数据源</li></li>' +
                    '<li class="hide" ref=".area" defaultName="数据表">数据表</li>' +
                    '</ul>' +
                    '</div>' +
                    '<div class="city-area">' +
                    '<div class="tab-pane active city">' +
                    '<dl class="attr-list">' +
                    '<dd class="attr-list-body" id="' + addressId[i] + '">' +
                    '</dd>' +
                    '</dl>' +
                    '</div>' +
                    '<div class="tab-pane area">' +
                    '<dl class="attr-list">' +
                    '<dd class="attr-list-body">' +
                    '</dd>' +
                    '</dl>' +
                    '</div>' +
                    '<div class="attr-bar"><a class="btn             blue-btn attrSureBtn mr10">确定</a><a class="btn btn-small gray-btn attrCancelBtn">清除</a></div>' +
                    '</div>' +
                    '</div>' +
                    '</div>';
                $("#" + n).append(areaHtml);
                $("#" + addressId[i]).html(tmpl(addressTmpl, addressArr));
            });
            $('.city-title li').click(function (event) {
                selectCurEpidemicTitle($(this));
                event.stopPropagation();
            });
            $(".tree-wrap").on("click", ".city-area label", function (event) {
                var id = $(this).parents(".tree-wrap").parent().attr("id");
                curAreaVal = selectCurEpidemic(addressArr, $(this), id);
                event.stopPropagation();
            });
            // 防止关闭
            $(".tree-wrap").on("click", ".city-area", function (event) {
                event.stopPropagation();
            });
            $(".attrSureBtn").click(function () {
                if (options.callback) {
                    options.callback(curAreaVal);
                }
                $('.dropdown-menu').click();
            });
            $(".attrCancelBtn").click(function () {
                var $treeWrap = $(this).parents('.tree-wrap');
                $treeWrap.find(".selectedArea").html("请选择");
                $treeWrap.find("input").val("");
                $.each($treeWrap.find("li"), function (i, n) {
                    if (i == 0) {
                        $(n).addClass("active");
                    } else {
                        $(n).addClass("hide").removeClass("active");
                    }
                    $(n).html($(n).attr("defaultname"));
                });
                $treeWrap.find("label").removeClass("active");
                $treeWrap.find(".city-title li:first").click();
                $('.dropdown-menu').click();
            });
            // 展开收缩
            $(".tree-wrap .dropdown-toggle").click(function () {
                if ($(this).closest('.form-control').attr('readonly')) { //如果控件禁止编辑，就不做处理；
                    $(this).removeAttr('data-toggle').css('cursor', 'not-allowed');
                    return;
                }
                var height = $(this).next().height();
            })
        }
        /**
         * 获取下级数据
         * @param {obj} addressArr 疫情数据
         * @param {string} SERVICE_NAME 选中数据源
         * @return {obj} 返回下级数据
         */
        function queryEpidemicChildNodes(addressArr, SERVICE_NAME) {
            var titleDomArr = $(".city-title li");
            var titleArr = [];
            $.each(titleDomArr, function (i, n) {
                titleArr.push($(n).text().trim())
            })
            var index = titleArr.indexOf(SERVICE_NAME);
            titleArr.length = index + 1;
            var tmpAddressArr = addressArr
            $.each(titleArr, function (i, n) {
                for (var k = 0; k < tmpAddressArr.length; k++) {
                    if (n == tmpAddressArr[k].SERVICE_NAME) {
                        tmpAddressArr = tmpAddressArr[k].ChildNodes
                        break;
                    }
                }
            })
            return tmpAddressArr;
        }
        /**
         * 级联操作主逻辑
         * @param {obj} addressArr 疫情总数据
         * @param {string} $this 选中label
         * @param {string} id 地址树容器id
         * @return {string} 返回当前选中文本
         */
        function selectCurEpidemic(addressArr, $this, id) {
            // 当前标题
            var $curTitleLi = $this.parents(".dropdown-menu").find(".city-title li.active");
            // 设置标题
            $curTitleLi.html($this.html());
            // 处理请选择
            var $selectedArea = $this.parents(".tree-wrap").find(".selectedArea");
            // 选中label
            var NODE_ID = $this.attr("nodeid");
            var SERVICE_NAME = $this.attr("title");
            var area = '';//展示文本
            // 所有标题
            var $cityTitleLi = $this.parents(".dropdown-menu").find(".city-title li");
            var len = $cityTitleLi.length;
            $cityTitleLi.each(function (i) {
                area += $(this).text();
                if ($(this).hasClass("active")) {
                    return false;
                }
                if (i != (len - 1)) {
                    area += ' > ';
                }
            });
            $selectedArea.html(area);
            $selectedArea.next().val(NODE_ID);
            // 重新单击父级label
            if ($curTitleLi.next().length != 0) {
                // 还原下级标题
                $curTitleLi.nextAll().each(function () {
                    $(this).html($(this).attr("defaultName"));
                });
                // 更新body
                // 显示下级
                $curTitleLi.next().removeClass("hide");
                selectCurEpidemicTitle($curTitleLi.next());//点击后，active的li就改变了，要重新选择
                // 找到下级
                $curTitleLi = $this.parents(".dropdown-menu").find(".city-title li.active");
                // 获取下级body数据
                var nodeList = queryEpidemicChildNodes(addressArr, SERVICE_NAME);
                // 渲染下级
                $("#" + id + " " + $curTitleLi.attr("ref")).find("dd").html(tmpl("childNodeListTemplate", nodeList));
            }
            // 处理label的active
            $this.addClass("active").siblings().removeClass("active");
            return area;
        }

        /**
         * 点击标题切换辅助
         * @param {string} $this 选中的title的jqdom
         */
        function selectCurEpidemicTitle($this) {
            if (!$this.hasClass("disable")) {
                // 找到tab引用
                var ref = $this.attr('ref');
                // 找到父亲
                var $cityArea = $this.parents(".city-title").next();
                // 切换标题acitve
                $this.addClass('active').siblings().removeClass('active');
                // 切换tab
                $cityArea.find('.tab-pane').removeClass('active');
                $cityArea.find(ref).addClass('active');
            }
        }
    </script>
</body>

</html>